<script lang="ts" setup>
import type {
  VxeGridListeners,
  VxeTableGridOptions,
} from '#/adapter/vxe-table';
import type { MenuApi } from '#/api/types';

import { h, ref } from 'vue';

import { Page } from '@vben/common-ui';
import {
  FolderIcon,
  MenuIcon,
  OkButtonIcon,
  Plus,
  VbenIcon,
} from '@vben/icons';

import { Button, message, Modal, Tag } from 'ant-design-vue';

import { useVbenVxeGrid } from '#/adapter/vxe-table';
import {
  batchDeleteMenuApi,
  deleteMenuApi,
  getAllMenuListApi,
} from '#/api/core/modules/menu';
import { $t } from '#/locales';

// 引入菜单抽屉组件
import MenuDrawer from './modules/menu-drawer.vue';

// 菜单类型映射
const menuTypeMap = {
  C: { icon: MenuIcon, value: '菜单' },
  F: { icon: OkButtonIcon, value: '按钮' },
  M: { icon: FolderIcon, value: '目录' },
};

// 是否为外链
const externalMap = {
  0: { text: '否', color: 'default' },
  1: { text: '是', color: 'cyan' },
};

// 是否显示
const showMap = {
  0: { text: '隐藏', color: 'red' },
  1: { text: '显示', color: 'green' },
};

// 菜单状态
const statusMap = {
  1: { text: '正常', color: 'green' },
  2: { text: '停用', color: 'red' },
};

// 缓存
const cacheMap = {
  0: { text: '不缓存', color: 'default' },
  1: { text: '缓存', color: 'blue' },
};

// 菜单抽屉引用
const menuDrawerRef = ref();

// 选中的行
const selectedRows = ref<MenuApi.MenuTree[]>([]);

// 表格事件监听，与其他组件保持一致
const gridEvents: VxeGridListeners<MenuApi.MenuTree> = {
  checkboxAll: onSelectionChange,
  checkboxChange: onSelectionChange,
};

// 表格实例API
const [Grid, gridApi] = useVbenVxeGrid({
  gridEvents,
  gridOptions: {
    columns: [
      {
        field: 'id',
        width: 50,
        type: 'checkbox',
      },
      {
        field: 'menuName',
        title: $t('system.menu.menuName'),
        minWidth: 150,
        treeNode: true,
        slots: {
          // 需要i18n支持 否则返回原始值
          default: ({ row }) => $t(row.menuName),
        },
      },
      {
        field: 'icon',
        title: $t('system.menu.icon'),
        width: 80,
        slots: {
          default: ({ row }) => {
            if (row?.icon === '#') {
              return '';
            }
            return h('span', { class: 'flex justify-center' }, [
              h(VbenIcon, { icon: row.icon }),
            ]);
          },
        },
      },
      {
        field: 'menuType',
        title: $t('system.menu.type'),
        width: 80,
        slots: {
          default: ({ row }) => {
            const current = menuTypeMap[row.menuType as 'C' | 'F' | 'M'];
            if (!current) {
              return '未知';
            }
            return h(
              'span',
              { class: 'flex items-center justify-center gap-1' },
              [
                h(current.icon, { class: 'size-[18px]' }),
                h('span', current.value),
              ],
            );
          },
        },
      },
      {
        field: 'sort',
        title: $t('system.menu.sort'),
        width: 80,
      },
      {
        field: 'routePath',
        title: $t('system.menu.path'),
        minWidth: 120,
      },
      {
        field: 'componentPath',
        title: $t('system.menu.componentPath'),
        minWidth: 180,
      },
      {
        field: 'perms',
        title: $t('system.menu.perms'),
        minWidth: 150,
      },
      {
        field: 'isExternal',
        title: $t('system.menu.isExternal'),
        width: 80,
        slots: {
          default: ({ row }) => {
            const type =
              externalMap[row.isExternal as keyof typeof externalMap];
            return h(Tag, { color: type.color }, () => type.text);
          },
        },
      },
      {
        field: 'isShow',
        title: $t('system.menu.isShow'),
        width: 80,
        slots: {
          default: ({ row }) => {
            const type = showMap[row.isShow as keyof typeof showMap];
            return h(Tag, { color: type.color }, () => type.text);
          },
        },
      },
      {
        field: 'status',
        title: $t('system.menu.status'),
        width: 80,
        slots: {
          default: ({ row }) => {
            const type = statusMap[row.status as keyof typeof statusMap];
            return h(Tag, { color: type.color }, () => type.text);
          },
        },
      },
      {
        field: 'isCache',
        title: $t('system.menu.isCache'),
        width: 80,
        slots: {
          default: ({ row }) => {
            const type = cacheMap[row.isCache as keyof typeof cacheMap];
            return h(Tag, { color: type.color }, () => type.text);
          },
        },
      },
      {
        align: 'center',
        slots: {
          default: ({ row }) => {
            return h('div', { class: 'flex items-center justify-center' }, [
              h(
                Button,
                {
                  size: 'small',
                  class: 'text-blue-700 border-blue-700',
                  onClick: () => onEdit(row),
                },
                () => '编辑',
              ),
              h(
                Button,
                {
                  size: 'small',
                  class: 'ml-2 text-green-700 border-green-700',
                  onClick: () => onAddSubMenu(row),
                },
                () => '新增',
              ),
              h(
                Button,
                {
                  size: 'small',
                  class: 'ml-2 text-red-500 border-red-500',
                  onClick: () => onDelete(row, 0),
                },
                () => '删除',
              ),
              h(
                Button,
                {
                  size: 'small',
                  class: 'ml-2 text-red-500 border-red-500',
                  onClick: () => onDelete(row, 1),
                },
                () => '级联删除',
              ),
            ]);
          },
        },
        field: 'operation',
        fixed: 'right',
        title: $t('ui.table.action'),
        width: 260,
      },
    ],
    height: 'auto',
    keepSource: true,
    proxyConfig: {
      ajax: {
        query: async () => {
          try {
            const result = await getAllMenuListApi();
            // 处理返回数据结构，确保有records和total字段
            return {
              records: result.data || [],
              total: Array.isArray(result.data) ? result.data.length : 0,
            };
          } catch {
            message.error('获取菜单数据失败');
            return {
              records: [],
              total: 0,
            };
          }
        },
      },
    },
    rowConfig: {
      keyField: 'id',
      isHover: true,
    },
    toolbarConfig: {
      custom: true,
      export: false,
      refresh: { code: 'query' },
      zoom: true,
    },
    checkboxConfig: {
      checkField: 'checked',
      checkStrictly: false,
      highlight: true,
    },
    treeConfig: {
      childrenField: 'children',
      indent: 20,
      showIcon: true,
    },
  } as VxeTableGridOptions<MenuApi.MenuTree>,
});

// 监听选择变化事件
function onSelectionChange(params: {
  checked: boolean;
  records: MenuApi.MenuTree[];
}) {
  const rows = params.records;
  selectedRows.value = rows || [];
}

// 确认弹窗
function confirm(content: string, title: string) {
  return new Promise((resolve, reject) => {
    Modal.confirm({
      content,
      onCancel() {
        reject(new Error('已取消'));
      },
      onOk() {
        resolve(true);
      },
      title,
    });
  });
}

// 创建菜单
function onCreate() {
  menuDrawerRef.value.drawerApi.setData({ update: false });
  menuDrawerRef.value.drawerApi.open();
}

// 创建子菜单
function onAddSubMenu(row: MenuApi.MenuTree) {
  menuDrawerRef.value.drawerApi.setData({
    update: false,
    parentId: row.id,
  });
  menuDrawerRef.value.drawerApi.open();
}

// 编辑菜单
function onEdit(row: MenuApi.MenuTree) {
  menuDrawerRef.value.drawerApi.setData({
    id: row.id,
    update: true,
  });
  menuDrawerRef.value.drawerApi.open();
}

// 删除菜单
async function onDelete(row: MenuApi.MenuTree, deepDelete: number) {
  await confirm(
    $t('ui.actionMessage.delete', [row.menuName]),
    $t('ui.actionTitle.delete', [$t('system.menu.name')]),
  );
  const result = await deleteMenuApi({ id: row.id, deepDelete });
  if (result.success) {
    message.success('删除成功');
  } else {
    message.error(result.message);
  }
  onRefresh();
}

// 批量删除菜单
async function onBatchDelete() {
  if (selectedRows.value.length === 0) {
    message.warning('请先选择要删除的菜单');
    return;
  }

  try {
    await confirm(
      `确定要删除选中的 ${selectedRows.value.length} 个菜单吗？`,
      '批量删除菜单',
    );

    // 获取所有选中菜单的ID
    const ids = selectedRows.value.map((row) => row.id);

    // 调用批量删除接口
    const result = await batchDeleteMenuApi(ids);
    if (result.success) {
      message.success('批量删除成功');
    }
    onRefresh();
  } catch (error) {
    console.error(error);
  }
}

// 刷新列表
function onRefresh() {
  gridApi.reload();
}
</script>

<template>
  <Page auto-content-height>
    <Grid :table-title="$t('system.menu.list')">
      <template #toolbar-tools>
        <Button type="primary" @click="onCreate">
          <Plus class="size-5" />
          {{ $t('ui.actionTitle.create', [$t('system.menu.name')]) }}
        </Button>
        <Button danger class="ml-2" @click="onBatchDelete"> 批量删除 </Button>
      </template>
    </Grid>

    <!-- 菜单抽屉组件 -->
    <MenuDrawer ref="menuDrawerRef" @reload="onRefresh" />
  </Page>
</template>
